Skip to content

Harden Linux manager executable lookup to prevent PATH hijacking#4621

Merged
Gabriel Dufresne (GabrielDuf) merged 1 commit intomainfrom
codex/fix-path-hijacking-vulnerability-in-linux-managers
Apr 22, 2026
Merged

Harden Linux manager executable lookup to prevent PATH hijacking#4621
Gabriel Dufresne (GabrielDuf) merged 1 commit intomainfrom
codex/fix-path-hijacking-vulnerability-in-linux-managers

Conversation

@mmorrissette-devolutions
Copy link
Copy Markdown
Contributor

Motivation

  • Close a local privilege-escalation vector where apt, dnf, and pacman binaries were discovered from the user PATH and later invoked under an elevator (sudo/pkexec), which allowed a PATH-hijacked binary to be run as root after user approval.
  • Restrict manager executable discovery to known system locations to retain required elevation behavior while removing attacker-controlled PATH influence.

Description

  • Changed FindCandidateExecutableFiles() in src/UniGetUI.PackageEngine.Managers.Apt/Apt.cs to only consider /usr/bin/apt and /bin/apt instead of using CoreTools.WhichMultiple("apt").
  • Changed FindCandidateExecutableFiles() in src/UniGetUI.PackageEngine.Managers.Dnf/Dnf.cs to only consider /usr/bin/dnf5, /usr/bin/dnf, /bin/dnf5, and /bin/dnf and removed WhichMultiple usage for dnf candidates.
  • Changed FindCandidateExecutableFiles() in src/UniGetUI.PackageEngine.Managers.Pacman/Pacman.cs to only consider /usr/bin/pacman and /bin/pacman instead of using CoreTools.WhichMultiple("pacman").
  • Preserved the rest of the managers' behavior and the existing elevation flow, so the first available trusted path is still selected for operations that require admin rights.

Testing

  • No automated unit or integration tests were executed because the environment lacks the .NET toolchain; dotnet --version returned command not found so dotnet test could not be run.
  • Performed local code inspection and diff verification to ensure only the candidate discovery lists were modified and no operation/elevation code paths were changed.

Codex Task

@GabrielDuf Gabriel Dufresne (GabrielDuf) merged commit 335578e into main Apr 22, 2026
1 check passed
@GabrielDuf Gabriel Dufresne (GabrielDuf) deleted the codex/fix-path-hijacking-vulnerability-in-linux-managers branch April 22, 2026 13:49
@GabrielDuf Gabriel Dufresne (GabrielDuf) restored the codex/fix-path-hijacking-vulnerability-in-linux-managers branch April 22, 2026 13:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens Linux package manager executable discovery (apt/dnf/pacman) to avoid selecting binaries from the user-controlled PATH that may later be executed under elevation (sudo/pkexec).

Changes:

  • Replace CoreTools.WhichMultiple(...)-based discovery with fixed, trusted absolute paths for apt and pacman.
  • Replace CoreTools.WhichMultiple(...)-based discovery with fixed, trusted absolute paths for dnf/dnf5.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/UniGetUI.PackageEngine.Managers.Apt/Apt.cs Restricts apt candidate lookup to /usr/bin/apt and /bin/apt.
src/UniGetUI.PackageEngine.Managers.Dnf/Dnf.cs Restricts dnf/dnf5 candidate lookup to /usr/bin/* and /bin/*.
src/UniGetUI.PackageEngine.Managers.Pacman/Pacman.cs Restricts pacman candidate lookup to /usr/bin/pacman and /bin/pacman.
Comments suppressed due to low confidence (1)

src/UniGetUI.PackageEngine.Managers.Dnf/Dnf.cs:63

  • This candidate list uses File.Exists only; on Linux this can include non-executable files and cause the manager to be considered available even though the binary can’t be executed. Add an executability check (execute bits) or use CoreTools.WhichMultiple/Which with absolute paths to validate executability without relying on PATH search.
        var candidates = new List<string>();
        foreach (var path in new[] { "/usr/bin/dnf5", "/usr/bin/dnf", "/bin/dnf5", "/bin/dnf" })
        {
            if (File.Exists(path) && !candidates.Contains(path))
                candidates.Add(path);
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +54 to 58
var candidates = new List<string>();
foreach (var path in new[] { "/usr/bin/pacman", "/bin/pacman" })
{
if (File.Exists(path) && !candidates.Contains(path))
candidates.Add(path);
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FindCandidateExecutableFiles currently accepts any existing file at these locations, even if it isn’t executable (no +x). Consider checking Unix execute permissions (or using CoreTools.WhichMultiple/Which with absolute paths) so the manager isn’t marked found when the binary can’t be launched.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to 59
var candidates = new List<string>();
foreach (var path in new[] { "/usr/bin/apt", "/bin/apt" })
{
if (File.Exists(path) && !candidates.Contains(path))
candidates.Add(path);
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Candidate discovery only checks File.Exists; it will treat non-executable files (missing +x) as valid candidates and may mark the manager as found, then later fail to launch with a permission error. Consider additionally verifying executability (e.g., via Unix execute bits) or reusing CoreTools.WhichMultiple/Which on the absolute paths to leverage its executable-checking logic without searching PATH.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants